package com.quanyan.club.web;

import com.alibaba.fastjson.JSON;
import com.quanyan.api.APIResponse;
import com.quanyan.api.enums.ApiResponseEnum;
import com.quanyan.club.constants.ClubConstants;
import com.quanyan.club.entity.db.TbClub;
import com.quanyan.club.entity.db.TbClubBindAccount;
import com.quanyan.club.entity.vo.req.ReqClubAccountBind;
import com.quanyan.club.entity.vo.req.ReqClubWidthdrawApply;
import com.quanyan.club.entity.vo.req.ReqClubWidthdrawApplyList;
import com.quanyan.club.entity.vo.resp.RespClubBindAccount;
import com.quanyan.club.entity.vo.resp.RespClubWidthdrawRecord;
import com.quanyan.club.exception.ClubEnum;
import com.quanyan.club.mapper.TbClubBindAccountMapper;
import com.quanyan.club.mapper.TbClubMapper;
import com.quanyan.club.service.ClubMemberService;
import com.quanyan.club.service.ClubWidthdrawService;
import com.quanyan.club.sms.ClubSmsService;
import com.quanyan.common.Plugin.PageObj;
import com.quanyan.common.exception.BizException;
import com.quanyan.orderpay.request.ReqWithdrawFormData;
import com.quanyan.orderpay.service.OrderPayService;
import com.quanyan.redisCluster.config.RedisTemplate;
import com.quanyan.redisCluster.utils.RedisConstants;
import com.quanyan.redisCluster.utils.RedisKey;
import com.quanyan.user.response.RespUserInfoDetail;
import com.quanyan.user.serviceFacade.UserServiceFacade;
import org.apache.commons.collections.MapUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

/**
 * Created by zhuo.shi on 2016/6/20.
 */
@RestController
public class ClubWidthdrawController extends BaseController {

    private static Logger logger = Logger.getLogger(ClubWidthdrawController.class);

    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private ClubWidthdrawService clubWidthdrawService;
    @Autowired
    private ClubSmsService smsService;
    @Autowired
    private OrderPayService orderPayService;
    @Autowired
    private TbClubBindAccountMapper clubBindAccountMapper;
    @Autowired
    private ClubMemberService clubMemberService;

    /**
     * 绑定俱乐部提现账号
     */
    @RequestMapping("/api/club/widthdraw/account/bind")
    public APIResponse bindClubAccount(@RequestBody ReqClubAccountBind reqClubAccountBind, HttpServletRequest request) {
        int uid = getUid(request, true);
        int clubId = reqClubAccountBind.getClubId();
        int accountType = reqClubAccountBind.getAccountType();
        String accountNo = reqClubAccountBind.getAccountNo();
        String name = reqClubAccountBind.getName();
        String phone = reqClubAccountBind.getPhone();
        if (accountType == ClubConstants.WITHDRAW_BY_ALIPAY){
            //从缓存获取验证码,比对手机验证码
            APIResponse apiResponse = smsService.checkCode(reqClubAccountBind.getCode(), phone);
            if (!apiResponse.isRet() || apiResponse.getErrcode() != 200) {
                return APIResponse.returnFail(ApiResponseEnum.VALIDATE_CODE_ERROR);

            }
        }
        if (!clubMemberService.isClubMasterMember(uid, clubId)){    //只能是俱乐部主席可以绑定
            return APIResponse.returnFail(ApiResponseEnum.PERMISSION_DENIED);
        }
        boolean isBind = clubWidthdrawService.isAccountBind(clubId, uid, accountType, accountNo);
        if (isBind){
            return APIResponse.returnFail(ClubEnum.CLUB_ACCOUNT_IS_BINDING);
        }
        return clubWidthdrawService.bindClubAccount(clubId, uid, accountType, accountNo, name, phone, reqClubAccountBind.getAccountAvatar());
    }

    /**
     * 解绑俱乐部提现账号
     */
    @RequestMapping("/api/club/widthdraw/account/unbind")
    public APIResponse unbindClubAccount(@RequestBody ReqClubAccountBind reqClubAccountUnbind, HttpServletRequest request) {

        int clubId = reqClubAccountUnbind.getClubId();
        int accountType = reqClubAccountUnbind.getAccountType();
        String accountNo = reqClubAccountUnbind.getAccountNo();
        String code = reqClubAccountUnbind.getCode();
        String phone = reqClubAccountUnbind.getPhone();

        //从缓存获取验证码,比对手机验证码
        APIResponse apiResponse = smsService.checkCode(code, phone);
        if (!apiResponse.isRet() || apiResponse.getErrcode() != 200) {
            return APIResponse.returnFail(ApiResponseEnum.VALIDATE_CODE_ERROR);
        }
        int uid = getUid(request, true);
        if (!clubMemberService.isClubMasterMember(uid, clubId)){    //只能是俱乐部主席可以解绑
            return APIResponse.returnFail(ApiResponseEnum.PERMISSION_DENIED);
        }
        boolean isBind = clubWidthdrawService.isAccountBind(clubId, uid, accountType, accountNo);
        if (!isBind){
            return APIResponse.returnFail(ClubEnum.CLUB_ACCOUNT_NOT_BIND);  //还没有绑定
        }
        return APIResponse.returnSuccess(clubWidthdrawService.unbindClubAccount(clubId, uid, accountType, accountNo));
    }

    /**
     * 获取俱乐部绑定的账户
     */
    @RequestMapping(value = "/api/club/widthdraw/account/getbind")
    public APIResponse<RespClubBindAccount> getClubBindAccount(@RequestBody Map<String, String> map){
        if (!map.containsKey("clubId")){
            return APIResponse.returnFail(ApiResponseEnum.PARAMETER_CANT_BE_EMPTY);
        }
        return APIResponse.returnSuccess(clubWidthdrawService.getClubUnbindAccount(MapUtils.getInteger(map, "clubId")));
    }

    /**
     * 获取要解绑的账户信息，并发送手机验证码
     * @param map        包括key=id, value=tb_club_bin_account.id
     */
    @RequestMapping("/api/club/widthdraw/account/getunbind/sendcode")
    public APIResponse<RespClubBindAccount> getClubUnbindAccount(@RequestBody Map<String, String> map){
        TbClubBindAccount bindAccount = clubBindAccountMapper.selectByPrimaryKey(MapUtils.getInteger(map, "id"));
        if (bindAccount == null){
            return APIResponse.returnFail(ApiResponseEnum.RECORD_DO_NOT_EXISTS);
        }
        RespClubBindAccount clubBindAccount =
        clubWidthdrawService.getClubUnbindAccount(bindAccount.getClubId());
        logger.warn("clubBindAccount=" + JSON.toJSONString(clubBindAccount));
        //发送手机验证码
        APIResponse apiResponse = smsService.sendSms(clubBindAccount.getPhone());
        if (apiResponse.isRet() && apiResponse.getErrcode() == 200){
            logger.debug("解绑俱乐部提现账号，发送手机验证码成功！");
            return APIResponse.returnSuccess(clubBindAccount);
        }else {
            return APIResponse.returnFail("短信验证码发送失败");
        }
    }

    /**
     * 解绑账户时重新发送手机验证码
     * @return
     */
    @RequestMapping("/api/club/widthdraw/account/unbind/resendcode")
    public APIResponse unbindClubAccountResendCode(@RequestBody Map<String, String> map){
        if (!map.containsKey("phone")){
            return APIResponse.returnFail(ApiResponseEnum.PARAMETER_CANT_BE_EMPTY);
        }
        APIResponse apiResponse = smsService.sendSms(map.get("phone"));
        if (apiResponse.isRet() && apiResponse.getErrcode() == 200){
            logger.debug("解绑俱乐部提现账号，发送手机验证码成功！");
            return APIResponse.returnSuccess();
        }else {
            return APIResponse.returnFail("短信验证码发送失败");
        }
    }

    /**
     * 获取俱乐部绑定的账号列表
     */
    @RequestMapping("/api/club/widthdraw/bind/account/list")
    public APIResponse<List<TbClubBindAccount>>  getClubBindAccounts(@RequestBody Map<String, String> map) {
        if (!map.containsKey("clubId")){
            return APIResponse.returnFail(ApiResponseEnum.PARAMETER_CANT_BE_EMPTY);
        }
        return APIResponse.returnSuccess(clubWidthdrawService.getClubBindAccounts(Integer.valueOf(map.get("clubId"))));
    }

    /**
     * 获取俱乐部可提现金额
     */
    @RequestMapping("/api/club/widthdraw/get/usablemoney")
    public APIResponse<BigDecimal> getUsableWidthdrawAmount(@RequestBody Map<String, String> map) {
        if (!map.containsKey("clubId")){
            return APIResponse.returnFail(ApiResponseEnum.PARAMETER_CANT_BE_EMPTY);
        }
        return APIResponse.returnSuccess(clubWidthdrawService.getUsableWidthdrawAmount(MapUtils.getInteger(map, "clubId")));
    }

    @Autowired
    private UserServiceFacade userServiceFacade;
    @Autowired
    TbClubMapper clubMapper;
    /**
     * 俱乐部申请提现（支付宝、微信提现申请）
     */
    @RequestMapping("/api/club/widthdraw/apply")
    public APIResponse applyClubWithdraw(@RequestBody ReqClubWidthdrawApply reqApply, HttpServletRequest request){

        int clubId = reqApply.getClubId();
        int accountType = reqApply.getAccountType();
        BigDecimal amount = reqApply.getAmount();
        String accountNo = reqApply.getAccountNo();

        TbClub tbClub = clubMapper.selectByPrimaryKey(clubId);
        if (tbClub == null || tbClub.getIsDelete() == 1){
            return APIResponse.returnFail("俱乐部被禁用！");
        }
        //获取当前登录的用户，判断是否有权限，俱乐部主席和财务管理员才有权限申请提现
        int uid = getUid(request, true);

        if(!clubMemberService.isClubAdminMember(uid, clubId)){
            return APIResponse.returnFail(ApiResponseEnum.PERMISSION_DENIED);
        }

        //校验是否通过了实名认证
        APIResponse<RespUserInfoDetail> response = userServiceFacade.queryUserInfoDetail(tbClub.getUid());
        if (response != null && response.isRet()){
            RespUserInfoDetail userDetail = response.getData();
             if (userDetail != null && userDetail.getNameVerifyStatusDe() != 2){
                 return APIResponse.returnFail("俱乐部主席还未实名认证通过！");
             }
        }else {
            return APIResponse.returnFail(ApiResponseEnum.USER_IS_NULL);
        }
        if (amount.compareTo(new BigDecimal(50)) < 0){
            throw new BizException("提现金额必须大于50元！");
        }

        //1. 判断申请提现次数是否已经超过3次
        RedisKey key = new RedisKey(RedisConstants.CLUB_FAMILY_KEY, clubId + ClubConstants.WITHDRAW_REDIS_KEY);
        if (redisTemplate.exists(key)) {
            Integer applyCount = (Integer) redisTemplate.get(key);
            if (applyCount >= 3){
                return APIResponse.returnFail(ClubEnum.CLUB_WITHDRAW_APPLY_COUNT_LIMIT);
            }
        }
        //2. 判断提现金额是否超过3万
        if (accountType == ClubConstants.WITHDRAW_BY_ALIPAY && amount.compareTo(new BigDecimal(5*10000)) > 0){
            return APIResponse.returnFail(ClubEnum.CLUB_WIDTHRAW_MAXAMOUNT_ALIPAY);
        }
        if (accountType == ClubConstants.WITHDRAW_BY_WEIXIN && amount.compareTo(new BigDecimal(2*10000)) > 0){
            return APIResponse.returnFail(ClubEnum.CLUB_WIDTHRAW_MAXAMOUNT_WEIXIN);
        }
        //3. 判断提现金额是否超过账户剩余金额
        BigDecimal usableAmount = clubWidthdrawService.getUsableWidthdrawAmount(clubId);
        if (usableAmount.compareTo(amount) < 0){
            return APIResponse.returnFail(ClubEnum.CLUB_WIDTHRAW_NO_FUND);
        }

        RedisKey limitKey = new RedisKey(RedisConstants.CLUB_FAMILY_KEY, ClubConstants.WITHDRAW_REDIS_LIMIT + clubId + ":" + uid);
        if(redisTemplate.exists(limitKey)) {
            throw new BizException("重复提交！");
        }else {
            redisTemplate.set(limitKey, clubId + "_" + uid);
        }
        //4. 申请提现
        try {
            Boolean applystatus = clubWidthdrawService.applyClubWithdraw(uid, clubId, amount, accountType, accountNo, request);
            redisTemplate.delteKey(limitKey);
            return APIResponse.returnSuccess(applystatus);
        }catch (Exception e) {
            redisTemplate.delteKey(limitKey);
            throw new BizException(e.getMessage());
        }
    }

    /**
     * 获取俱乐部提现记录列表（分页）
     */
    @RequestMapping("/api/club/widthdraw/recordlist")
    public APIResponse<PageObj<List<RespClubWidthdrawRecord>>> getWidthdrawRecords(@RequestBody Map<String, String> map){
        if (map.isEmpty() || !map.containsKey("clubId") || !map.containsKey("type")
                || !map.containsKey("pageNo") || !map.containsKey("pageSize")){
            APIResponse.returnFail(ApiResponseEnum.PARAMETER_CANT_BE_EMPTY);
        }
        int clubId = Integer.valueOf(map.get("clubId"));
        int type = Integer.valueOf(map.get("type"));     //提现状态（1 处理中，2 完成）
        int pageNo = Integer.valueOf(map.get("pageNo")) + 1;
        int pageSize = Integer.valueOf(map.get("pageSize"));
        int totalCount = clubWidthdrawService.countClubWidthdrawRecords(clubId, type);
        List<RespClubWidthdrawRecord> records = clubWidthdrawService.getClubWidthdrawRecords(clubId, type, pageNo, pageSize);
        return APIResponse.returnSuccess(PageObj.create(totalCount, pageNo, pageSize, records));
    }

    /**
     * 俱乐部提现申请列表
     * @return
     */
    @RequestMapping("/admin/api/club/withdraw/apply/list")
    public APIResponse withdrawApplyList(@RequestBody ReqClubWidthdrawApplyList reqListApply){
        return APIResponse.returnSuccess(clubWidthdrawService.getWithdrawApplies(reqListApply));
    }

    /**
     *  支付宝提现，“审核通过”时调用，发起支付宝批量付款
     *  (支付宝批量付款成功后，quanyan支付系统会通过MQ异步发送付款结果通知)
     * @return
     */
    @RequestMapping("/admin/api/club/widthdraw/byalipay/passaudit")
    public APIResponse withdrawByAlipayPassAudit(@RequestBody ReqWithdrawFormData reqWithdrawFormData){
        return APIResponse.returnSuccess(orderPayService.getBatchTransferFundByAlipayHtmlForm(reqWithdrawFormData));//调用支付系统
    }

    /**
     * 微信提现，“审核通过”时调用，发起微信转账
     */
    @RequestMapping("/admin/api/club/widthdraw/byweixin/passaudit")
    public APIResponse withdrawByWeixinPassAudit(@RequestBody ReqClubWidthdrawApply data){
        return clubWidthdrawService.withdrawByWeixinPassAudit(data.getClubId(), data.getAmount(), data.getAccountNo(), data.getName(), data.getWithdrawNo());
    }

}
